package cn.bdqn.controller.course;

import cn.bdqn.dto.LoginUser;
import cn.bdqn.pojo.course.Course;
import cn.bdqn.service.course.CourseCatalogService;
import cn.bdqn.service.course.CourseService;

import cn.bdqn.service.course.CourseVideoService;
import cn.bdqn.utils.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@RestController
@CrossOrigin
@RequestMapping("/api")
public class CourseController {

    @Autowired
    private CourseService courseService;
    @Autowired
    private CourseCatalogService courseCatalogService;
    @Autowired
    private CourseVideoService courseVideoService;

    @Autowired
    private RedisCache redisCache;
    /**
     * 查询所有课程信息
     * @return  返回课程信息集合
     */
    @GetMapping("/static/selectAllCourse")
    public Object selectAllCourse(){
        List<Course> list = courseService.selectAllCourse();
        return Json.isEmpty(list);
    }

    /**
     * 根据课程名称、当前页、每页数据条数、课程标签、课程状态查询课程信息
     * @param courseName    课程名称
     * @param currentPage   当前页
     * @param pageSize  数据条数
     * @param selectCourseTags  课程标签id数组
     * @param courseStatus  课程状态
     * @return  返回分页后课程信息集合
     */
    @GetMapping("/static/selectCourseByNameAndTagAndStatusAndPage")
    public Object selectCourseByNameAndPage(String courseName,Integer currentPage,Integer pageSize,Integer[] selectCourseTags,Integer courseStatus){
        if(null == currentPage || currentPage <0  || null == pageSize || pageSize < 0){
            return new Json(400,"当前页和分页大小不能为空");
        }else {
            //检查课程标签是否为空
            if(null != selectCourseTags&&selectCourseTags.length==0){
                selectCourseTags = null;
            }
            //检查状态属性是否为空
            if(null == courseStatus || courseStatus >1 || courseStatus<0){
                courseStatus = null;
            }

            PageHelper.startPage(currentPage,pageSize);
            List<Course> courses = courseService.selectCourseByNameAndTagAndStatusAndPage(courseName,selectCourseTags,courseStatus);
            return Json.isEmpty(new PageInfo<>(courses));
        }

    }

    /**
     * 根据课程状态查询课程信息数量
     * @param courseStatus  课程状态id
     * @return  返回课程信息集合
     */
    @PreAuthorize("hasAuthority('course:management')")
    @GetMapping("/selectCourseCountByStatus")
    public Object selectCourseCountByStatus(Integer courseStatus){
        Long courseCount = null;
        //检查课程状态是否为空
        if (null == courseStatus) {
            courseCount = courseService.selectCourseCount();
        }else {
            courseCount = courseService.selectCourseCountByStatus(courseStatus);
        }
        return Json.isEmpty(courseCount);
    }


    /**
     * 从缓存中获取所有课程id、名称，若没有则从数据库中获取
     * @return  返回课程信息集合
     */
    @PreAuthorize("hasAuthority('course:management')")
    @GetMapping("/selectCourseIdAndName")
    public Object selectCourseIdAndName(){
        //从缓存中获取课程信息
        List<Course> courses = redisCache.getCacheList(RedisConstants.COURSE_ID_NAME_KEY);
        //检查是否获取到数据
        if (null == courses || courses.size() == 0) {
            //获取所有在线课程信息
            courses = courseService.selectCourseIdAndName();
            //并将数据存放到缓存中
            redisCache.setCacheList(RedisConstants.COURSE_ID_NAME_KEY,courses);
        }

        return Json.isEmpty(courses);
    }
    @GetMapping("/selectCourseCount")
    public Object selectCourseCount(){
        List<Integer> integers = courseService.requestAll();
        return Json.isEmpty(integers);
    }

    /**
     * 根据课程标签id查询课程信息
     * @param tagIds    课程标签id数组
     * @return  返回查询得到的课程信息集合
     */
    @GetMapping("/static/selectCourseByTagId")
    public Object selectCourseByTagId(Integer[] tagIds){
        List<Course> courses = courseService.selectCourseByTagId(tagIds);
        return Json.isEmpty(courses);
    }

    /**
     * 根据课程id获取课程信息对象
     * @param courseId  课程id
     * @return  返回查询得到的课程对象
     */
    @GetMapping("/selectCourseById")
    public Object selectCourseById(Integer courseId){
        if (null == courseId || courseId < 0) {
            return new Json(400,"课程id不能为空");
        }else {
            Course course = courseService.selectCourseById(courseId);
            return Json.isEmpty(course);
        }
    }


    /**
     * 上传课程封面图片
     * @param file  上传图片文件
     * @param oldFilePath   原图文件路径
     * @param realPath  文件存放绝对路径
     * @param courseImgPath 图片位置相对路径
     * @return  返回图片相对路径
     * @throws Exception   上传异常
     */
    @PreAuthorize("hasAuthority('course:management')")
    @PostMapping("/uploadCourseImg")
    public Object uploadCourseImg(@RequestParam("courseImgFile") MultipartFile file,@RequestParam("oldFilePath") String oldFilePath, @Value("${prop.realPath}") String realPath ,@Value("${prop.upload-img.course-img}")String courseImgPath) throws Exception {
        //检查文件对象是否为空
        if (null == file) {
            return new Json(400,"上传文件不能为空");
        }
        //检查旧图片路径是否为空
        if (null != oldFilePath && oldFilePath.trim().length() > 0) {
            //删除原图片
            boolean b = FileSystemUtils.deleteRecursively(new File(realPath + oldFilePath));
            if (!b) {
                return new Json(400,"原图删除失败");
            }
        }

        FileUpload fileUpload = new FileUpload(courseImgPath);
        try {
            String url = fileUpload.upload(realPath, file);
            if (null == url) {
                return new Json(400,"未找到文件存放地址");
            }else {
                System.out.println(url);
                return new Json(200,"上传成功",url);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return new Json(400,"上传失败");
        }
    }

    /**
     * 创建课程
     * @param course    课程信息对象
     * @param request
     * @return  返回json对象
     */
    @PreAuthorize("hasAuthority('course:management')")
    @PostMapping("/createCourse")
    public Object createCourse(@RequestBody Course course,HttpServletRequest request,@Value("${prop.realPath}") String realPath){
        System.out.println(course);
        //检查课程名称是否为空
        if (null == course.getCourseName() || course.getCourseName().trim().length() == 0) {
            return new Json(400,"课程名称不能为空");
        }

        //检查课程封面路径是否为空
        if(null == course.getCourseCoverPath() || course.getCourseCoverPath().trim().length() == 0){
            //设置默认路径
            course.setCourseCoverPath("default");
        }else {
            //查看文件是否存在
            File folder = new File(realPath+course.getCourseCoverPath());
            if(!folder.exists()){
                return new Json(400,"上传文件不存在");
            }
        }

        //检查课程售价是否为空或小于0
        if(null == course.getCoursePrice() || course.getCoursePrice() < 0){
            //将课程售价设置为0
            course.setCoursePrice(0.0);
        }

        //获取登录用户id
        LoginUser principal = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer userid = principal.getUser().getUserId();
        if (Objects.isNull(userid)) {
            throw new RuntimeException("用户未登录");
        }

        //设置用户id
        course.setCourseCreateUserId(userid);

        //设置课程创建时间
        course.setCourseCreateDate(new Date());

        //创建课程信息
        Integer result = courseService.insertCourse(course);

        if (result >= 1) {
            //删除redis中的课程信息
            redisCache.deleteObject(RedisConstants.COURSE_ID_NAME_KEY);
            return new  Json(200,"课程创建成功",course.getCourseId());
        }else {
            return new Json(400,"课程创建失败");
        }
    }

    /**
     * 删除课程信息以及该课程下目录、视频信息
     * @param courseId  课程id
     * @param realPath  文件存放绝对路径
     * @param videoPath 视频相对路径
     * @return  返回json对象
     */
    @PreAuthorize("hasAuthority('course:management')")
    @DeleteMapping("/deleteCourseById")
    @Transactional(rollbackFor = Exception.class)
    public Object deleteCourseById(Integer courseId, @Value("${prop.realPath}") String realPath,@Value("${prop.upload-video}") String videoPath){
        Json json = null;

        //删除数据库中的视频信息
        int i = courseVideoService.deleteCourseVideoByCourseId(courseId);
        if (i<0){
            throw new RuntimeException("课程视频删除失败");
        }else {
            //删除目录
            int j = courseCatalogService.deleteCourseCatalogByCourseId(courseId);
            if (j<0){
                throw new RuntimeException("课程目录删除失败");
            }else {
                //删除课程信息
                Integer integer = courseService.deleteCourseById(courseId);
                if(integer < 0){
                    throw new RuntimeException("课程信息删除失败");
                }else {
                    //删除视频文件
                    boolean b = FileSystemUtils.deleteRecursively(new File(realPath+videoPath+"/"+courseId));
                    if (b) {
                        //删除redis中的课程信息
                        redisCache.deleteObject(RedisConstants.COURSE_ID_NAME_KEY);
                        json = new Json(200,"删除成功");
                    }else {
                        throw new RuntimeException("视频文件删除失败");
                    }
                }
            }

        }
        return json;
    }

    /**
     * 根据课程id修改课程信息
     * @param course    修改的课程信息对象
     * @return  返回json对象
     */
    @PreAuthorize("hasAuthority('course:management')")
    @PutMapping("/updateCourseById")
    public Object updateCourseById(@RequestBody Course course){
        System.out.println(course);
        //检查课程id是否为空
        if(null == course || course.getCourseId() == null){
            return new Json(400,"课程id不能为空");
        }else {
            //调用动态更新方法
            Integer integer = courseService.updateCourseById(course);
            //检查执行行数
            if(integer >= 1){
                //删除redis中的课程信息
                redisCache.deleteObject(RedisConstants.COURSE_ID_NAME_KEY);
                return new Json(200,"修改成功");
            }else {
                return new Json(400,"修改失败");
            }
        }
    }

    /**
     * 根据课程id修改课程状态信息
     * @param courseId  课程id
     * @param courseStatus  修改后的课程状态信息
     * @return  返回json对象
     */
    @PreAuthorize("hasAuthority('course:management')")
    @PutMapping("/updateCourseStatusByCourseId")
    public Object updateCourseStatusByCourseId(@RequestParam("courseId") Integer courseId,@RequestParam("courseStatus") Integer courseStatus){
        System.out.println(courseId);
        System.out.println(courseStatus);
        //检查课程id是否为空
        if (null == courseId || courseId <0) {
            return new Json(400,"课程id不能为空");
        }
        //检查课程状态是否异常
        if (null == courseStatus || courseStatus>1 || courseStatus<0) {
            return new Json(400,"课程状态异常");
        }

        Integer integer = courseService.updateCourseStatusById(courseId, courseStatus);
        if(integer >= 1){
            //删除redis中的课程信息
            redisCache.deleteObject(RedisConstants.COURSE_ID_NAME_KEY);
            return new Json(200,"修改成功");
        }else {
            return new Json(400,"修改失败");
        }
    }
}
